home *** CD-ROM | disk | FTP | other *** search
/ SGI Hot Mix 17 / Hot Mix 17.iso / HM17_SGI / research / examples / demo / demosrc / d_tankleak.pro < prev    next >
Text File  |  1997-07-08  |  53KB  |  1,611 lines

  1. ;valid $Id: d_tankleak.pro,v 1.26 1997/04/28 21:12:36 alan Exp $
  2. ;
  3. ;  Copyright (c) 1997, Research Systems, Inc. All rights reserved.
  4. ;       Unauthorized reproduction prohibited.
  5. ;
  6. ;+
  7. ;  FILE:
  8. ;       d_tankleak.pro
  9. ;
  10. ;  CALLING SEQUENCE: d_tankleak
  11. ;
  12. ;  PURPOSE:  Shows the contamination of leaky tanks.
  13. ;
  14. ;  MAJOR TOPICS: Visualization
  15. ;
  16. ;  CATEGORY:
  17. ;       IDL 5.0
  18. ;
  19. ;  INTERNAL FUNCTIONS and proCEDURES:
  20. ;       fun index_color2rgb     - Cnage the color index into RGB
  21. ;       fun read_bores          - Read bore holes data
  22. ;       pro em_win3D_event      - Drawing area event handler
  23. ;       pro em_volume_bounds    - Draw the volume 
  24. ;       fun em_extent_bounds    - Drawing a box (event handler)
  25. ;       pro em_gen_iso          - Compute the isosurface
  26. ;       pro em_menu_event       - menu bar event handler
  27. ;       pro em_option_event     - option event handler
  28. ;       pro em_view_event       - view event handler
  29. ;       pro d_tankleak_event      - main event handler
  30. ;       pro d_tankleak_Cleanup    - Cleanup
  31. ;       pro d_tankleak            - Main procedure
  32. ;
  33. ;  EXTERNAL FUNCTIONS, proCEDURES, and FILES:
  34. ;       pro trackball__define   - Create the trackball object
  35. ;       fun gettips             - REad the tip file
  36. ;       fun widtips             - Create the tip widgets
  37. ;       fun sizetips            - Size the tip widgets
  38. ;       vol1.sav
  39. ;       vol2.sav
  40. ;       bores0.dat
  41. ;       tanks.gif
  42. ;       tankleak.txt
  43. ;       tankleak.tip
  44. ;
  45. ;  REFERENCE: IDL Reference Guide, IDL User's Guide
  46. ;
  47. ;  NAMED STRUCTURES:
  48. ;       none.
  49. ;
  50. ;  COMMON BLOCS:
  51. ;       none.
  52. ;
  53. ;  MODifICATION HISTORY:  WRITTEN, SDG, RSI, DEC, 1996.
  54. ;
  55. ;-
  56. ;-----------------------------------------------------------
  57. ;
  58. ;    PURPOSE Convert an array of index color
  59. ;            to an array of RGB color. The function returns
  60. ;            the RGB colr array.
  61. ;
  62. function index_color2rgb, $
  63.     index_color, $   ; IN: array of index colors to convert
  64.     range            ; IN: range of the color wheel
  65.                      ;      to use for the conversion
  66.  
  67.     ;  Find min index_color.
  68.     ;
  69.     imin = FLOAT(MIN(index_color, MAX=imax))
  70.  
  71.     hue = range * (index_color-imin) / (imax-imin)
  72.     sat = 1.0
  73.     val = 1.0
  74.     n = N_ELEMENTS(hue)
  75.     color_convert, hue, REPLICATE(sat, n), REPLICATE(val,n), $
  76.          r,g,b, /HSV_RGB
  77.  
  78.     RETURN, TRANSPOSE([[r],[g],[b]])
  79.  
  80. end ; end function vert_col
  81.  
  82.  
  83. ;-----------------------------------------------------------
  84. ;
  85. ;    PURPOSE Read a bore hole file
  86. ;
  87. function read_bores, $
  88.     file_lun, $    ; IN: file lun 
  89.     parent_obj, $  ; IN: parent object
  90.     color          ; IN: assigned color
  91.  
  92.     ;  Read the title string.
  93.     ;
  94.     title = ' '
  95.     READF, file_lun, title
  96.  
  97.     ;  Read the number of boreholes.
  98.     ;
  99.     num_bores = 0
  100.     READF, file_lun, num_bores
  101.     num_points = 0
  102.     READF, file_lun, num_points
  103.  
  104.     x_coords = FLTARR(num_bores * num_points)
  105.     y_coords = FLTARR(num_bores * num_points)
  106.     z_coords = FLTARR(num_bores * num_points)
  107.     elem1   = FLTARR(num_bores * num_points)
  108.     elem2   = FLTARR(num_bores * num_points)
  109.     vert_col1 = INTARR(3,num_bores * num_points)
  110.     vert_col2 = INTARR(3,num_bores * num_points)
  111.     pl_num = num_points + 1
  112.     pl   = INTARR(num_bores * pl_num)
  113.     counter  = 0
  114.  
  115.     x = 0.0
  116.     y = 0.0
  117.     z = 0.0
  118.     val1 = 0.0
  119.     val2 = 0.0
  120.     bore_number = 0
  121.  
  122.     for i = 0, num_bores-1 do begin
  123.  
  124.         ;  Read the number of boreholes.
  125.         ;
  126.         READF, file_lun, bore_number
  127.  
  128.         pl[i*pl_num] = num_points
  129.         for j = 0, num_points-1 do begin
  130.             READF, file_lun, x, y, z, val1, val2
  131.             x_coords[counter] = x
  132.             y_coords[counter] = y
  133.             z_coords[counter] = z
  134.             elem1[counter] = val1
  135.             elem2[counter] = val2
  136.             pl[i*pl_num + j + 1] = counter
  137.             counter = counter + 1
  138.         endfor ; for j
  139.  
  140.     endfor ; for i
  141.  
  142.     ;  Compute the vertex colors for the polylines
  143.     ;
  144.     vert_col1 = index_color2rgb(elem1,225.0)
  145.  
  146.     vert_col2 = index_color2rgb(elem2,225.0)
  147.  
  148.     ;  Create the bores holes colored with
  149.     ;  the first element: element1.
  150.     ;
  151.     bore_obj = OBJ_NEW('IDLgrModel')
  152.     parent_obj->Add, bore_obj
  153.  
  154.     bore_obj_pl = OBJ_NEW('IDLgrPolyline', x_coords, y_coords, z_coords, $
  155.         POLYLINES=pl, THICK=2, VERT_COLOR=vert_col1)
  156.  
  157.     bore_obj->Add, bore_obj_pl
  158.  
  159.     ;  Return the bore object model.
  160.     ;
  161.     RETURN, bore_obj
  162.  
  163. end ; End read_bore
  164.  
  165. ;----------------------------------------------------------------------------
  166. ;
  167. ;  Purpose:  Handle rotations, quit on any button except left.
  168. ;
  169. pro em_win3d_event, $
  170.     sEvent                 ; IN: event sturcture
  171.  
  172.     WIDGET_CONTROL, sEvent.id, GET_UVALUE=uval, /NO_COPY
  173.  
  174.     WIDGET_CONTROL, sEvent.top, GET_UVALUE=state, /NO_COPY
  175.  
  176.  
  177.     ;  Expose.
  178.     ;
  179.     if (sEvent.type eq 4) then begin
  180.         state.oWindow->Draw, state.oView
  181.     endif
  182.  
  183.     ;  Handle trackball update.
  184.     ;
  185.     bHaveTransform = state.oTrack->Update(sEvent, TRANSFORM=qmat )
  186.     if (bHaveTransform NE 0) then begin
  187.         state.top3D->GetProperty, TRANSFORM=t
  188.         mt = t # qmat
  189.         state.top3D->SetProperty,TRANSFORM=mt
  190.     endif
  191.  
  192.     ;  Button press event.
  193.     ;
  194.     if (sEvent.type EQ 0) then begin    ; Button press.
  195.         state.btnDown = 1B
  196.         state.oWindow->SetProperty, QUALITY=state.dragq  ;Refresh quality
  197.         WIDGET_CONTROL, sEvent.id, /DRAW_MOTION
  198.     endif     ;   of  Button press
  199.  
  200.     ;  Button motion event.
  201.     ;
  202.     if ((sEvent.type eq 2) and (state.btndown eq 1b)) then begin
  203.         if (bHaveTransform) then begin
  204.             state.oWindow->Draw, state.oView
  205.         endif
  206.     endif    ;  end of Button motion
  207.  
  208.     ;  Button release.
  209.     ;
  210.     if (sEvent.type eq 1) then begin
  211.         state.btndown = 0b
  212.         state.oWindow->SetProperty, QUALITY=2
  213.         state.oWindow->Draw, state.oView
  214.         WIDGET_CONTROL, sEvent.id, DRAW_MOTION=0
  215.     endif    ;  end of Button release
  216.  
  217.     WIDGET_CONTROL, sEvent.top, SET_UVALUE=state, /NO_COPY
  218. end
  219.  
  220. ;----------------------------------------------------------------------------
  221. ;
  222. ;  Purpose: Draw a box around a volume.
  223. ;
  224. pro em_volume_bounds, $
  225.     volume, $   ; IN: volume data coordinates
  226.     color       ; IN: color of the box
  227.  
  228.     s = SIZE(volume)
  229.  
  230.     ;  Plot bottom 4 lines.
  231.     ;
  232.     PLOTS, [0.0,s[1]], [0.0,0.0], [0.0,0.0], COLOR=color, /T3D
  233.     PLOTS, [s[1],s[1]], [0.0,s[2]], [0.0,0.0], COLOR=color, /T3D
  234.     PLOTS, [s[1],0.0], [s[2],s[2]], [0.0,0.0], COLOR=color, /T3D
  235.     PLOTS, [0.0,0.0], [s[2],0.0], [0.0,0.0], COLOR=color, /T3D
  236.  
  237.     ;  Plot top 4 lines.
  238.     ;
  239.     PLOTS, [0.0,s[1]], [0.0,0.0], [s[3],s[3]], COLOR=color, /T3D
  240.     PLOTS, [s[1],s[1]], [0,s[2]], [s[3],s[3]], COLOR=color, /T3D
  241.     PLOTS, [s[1],0.0], [s[2],s[2]], [s[3],s[3]], COLOR=color, /T3D
  242.     PLOTS, [0.0,0.0], [s[2],0.0], [s[3],s[3]], COLOR=color, /T3D
  243.  
  244.     ;  Plot vertical 4 lines.
  245.     ;
  246.     PLOTS, [0.0,0.0], [0.0,0.0], [0.0,s[3]], COLOR=color, /T3D
  247.     PLOTS, [s[1],s[1]], [0.0,0.0], [0.0,s[3]], COLOR=color, /T3D
  248.     PLOTS, [s[1],s[1]], [s[2],s[2]], [0.0,s[3]], COLOR=color, /T3D
  249.     PLOTS, [0.0,0.0], [s[2],s[2]], [0.0,s[3]], COLOR=color, /T3D
  250.  
  251. end ; em_volume_bounds
  252.  
  253. ;----------------------------------------------------------------------------
  254. ;
  255. ;  Purpose: Draw a box given extents.
  256. ;
  257. ;           Exts = [xmin, xmax, ymin, ymax, zmin, zmax]
  258. ;           Exts = [  0     1     2     3    4      5 ]
  259. ;
  260. function em_extent_bounds, $
  261.     exts, $       ; IN: extents vector (see above)
  262.     parent_obj, $ ; IN: prent object of the box
  263.     color1, $     ; IN: color of x axis
  264.     color2, $     ; IN: color of y axis
  265.     color3        ; IN: color of z axis
  266.  
  267.     xverts = [exts[0], exts[1], exts[1], exts[0], $
  268.               exts[0], exts[1], exts[1], exts[0]]
  269.     yverts = [exts[2], exts[2], exts[3], exts[3], $
  270.               exts[2], exts[2], exts[3], exts[3]]
  271.     zverts = [exts[4], exts[4], exts[4], exts[4], $
  272.               exts[5], exts[5], exts[5], exts[5]]
  273.  
  274.     p1 = [5,0,1,2,3,0]
  275.     p2 = [2,0,4, $
  276.           2,1,5, $
  277.           2,2,6, $
  278.           2,3,7]
  279.     p3 = [5,4,5,6,7,4]
  280.  
  281.     pl = [5,0,1,2,3,0, $
  282.           5,4,5,6,7,4, $
  283.           2,0,4, $
  284.           2,1,5, $
  285.           2,2,6, $
  286.           2,3,7]
  287.  
  288.     box_obj = OBJ_NEW('IDLgrModel')
  289.     parent_obj->Add, box_obj
  290.  
  291.     box_top = OBJ_NEW('IDLgrpolyline',xverts, yverts, zverts, $
  292.         POLYLINES=p3,COLOR=color1)
  293.     box_bot = OBJ_NEW('IDLgrpolyline',xverts, yverts, zverts, $
  294.         POLYLINES=p1, COLOR=color3)
  295.     box_sides = OBJ_NEW('IDLgrpolyline',xverts, yverts, zverts, $
  296.         POLYLINES=p2, COLOR=color2)
  297.  
  298.     ;  Add the parts of the box to the box_obj.
  299.     ;
  300.     box_obj->Add, box_top
  301.     box_obj->Add, box_bot
  302.     box_obj->Add, box_sides
  303.  
  304.     RETURN, box_obj
  305.  
  306. end ; em_extent_bounds
  307.  
  308. ;----------------------------------------------------------------------------
  309. ;
  310. ;  Purpose:  Generate the isosurface.
  311. ;
  312. pro em_gen_iso, $
  313.     volume, $    ; IN: volume data
  314.     colors, $    ; IN: vertex colors
  315.     iso_value, $ ; IN: isometric value
  316.     low,  $      ; IN: lowest value to plot
  317.     verts, $     ; IN: vertices coordinates
  318.     polys,  $    ; IN: polygons coordinates
  319.     vert_color   ; IN: vertices colors
  320.  
  321.     vert_COLOR=colors
  322.  
  323.     SHADE_VOLUME, volume, iso_value, LOW=low, verts, polys, $
  324.         SHADES=vert_color
  325.  
  326. end ; EM_GEN_ISO
  327.  
  328. ;----------------------------------------------------------------------------
  329. ;
  330. ;  Purpose:  Main menu bar event handler.
  331. ;
  332. pro em_menu_event, $
  333.     sEvent   ; IN: event structure
  334.  
  335.     WIDGET_CONTROL, sEvent.id, GET_UVALUE=uval
  336.  
  337.     case uval of
  338.  
  339.         'QUIT' : begin
  340.             WIDGET_CONTROL, sEvent.top, /DESTROY
  341.         end ; Case of QUIT
  342.  
  343.         'INFO' : begin
  344.             if (Xregistered('XDisplayFile') NE 0) then RETURN
  345.  
  346.             XDisplayFile, filepath('tankleak.txt', $
  347.                 SUBDIR=['examples','demo','demotext']), $
  348.                 DONE_BUTTON='Done', $
  349.                 TITLE="About Environmental Modeling", $
  350.                 GROUP=sEvent.top, WIDTH=55, HEIGHT=14
  351.  
  352.         end   ; of INFO
  353.  
  354.     endcase ; of uval
  355.  
  356. end ; end of em_menu_event
  357.  
  358. ;----------------------------------------------------------------------------
  359. ;
  360. ;  Purpose:  Options menu event handler.
  361. ;
  362. pro em_option_event, $
  363.     sEvent   ; IN: event structure
  364.  
  365.     WIDGET_CONTROL, sEvent.id, GET_UVALUE=uval
  366.  
  367.     case uval of
  368.  
  369.         ;  Set the shading to flat.
  370.         ;
  371.         'FLAT': begin
  372.             WIDGET_CONTROL, sEvent.top, GET_UVALUE=state, /NO_COPY
  373.             WIDGET_CONTROL, state.wBase, SENSITIVE=0
  374.             WIDGET_CONTROL, state.wFlatButton, SENSITIVE=0
  375.             WIDGET_CONTROL, state.wGouraudButton, SENSITIVE=1
  376.             state.isosurface1->SetProperty, SHADING=0
  377.             state.oWindow->Draw, state.oView
  378.             WIDGET_CONTROL, state.wBase, SENSITIVE=1
  379.             WIDGET_CONTROL, sEvent.top, SET_UVALUE=state, /NO_COPY
  380.         end; Case of FLAT
  381.  
  382.         ;  Set the shading to Gouraud.
  383.         ;
  384.         'GOURAUD': begin
  385.             WIDGET_CONTROL, sEvent.top, GET_UVALUE=state, /NO_COPY
  386.             WIDGET_CONTROL, state.wBase, SENSITIVE=0
  387.             WIDGET_CONTROL, state.wFlatButton, SENSITIVE=1
  388.             WIDGET_CONTROL, state.wGouraudButton, SENSITIVE=0
  389.             state.isosurface1->SetProperty, SHADING=1
  390.             state.oWindow->Draw, state.oView
  391.             WIDGET_CONTROL, state.wBase, SENSITIVE=1
  392.             WIDGET_CONTROL, sEvent.top, SET_UVALUE=state, /NO_COPY
  393.         end; Case of GOURAUD
  394.  
  395.         ;  Set the surface style to wire.
  396.         ;
  397.         'WIRE': begin
  398.             WIDGET_CONTROL, sEvent.top, GET_UVALUE=state, /NO_COPY
  399.             WIDGET_CONTROL, state.wBase, SENSITIVE=0
  400.             state.isosurface1->SetProperty, STYLE=1
  401.             WIDGET_CONTROL, state.wWireButton, SENSITIVE=0
  402.             WIDGET_CONTROL, state.wSolidButton, SENSITIVE=1
  403.             state.oWindow->Draw, state.oView
  404.             WIDGET_CONTROL, state.wBase, SENSITIVE=1
  405.             WIDGET_CONTROL, sEvent.top, SET_UVALUE=state, /NO_COPY
  406.         end; Case of WIRE
  407.  
  408.         ;  Set the surface style to solid.
  409.         ;
  410.         'SOLID': begin
  411.             WIDGET_CONTROL, sEvent.top, GET_UVALUE=state, /NO_COPY
  412.             WIDGET_CONTROL, state.wBase, SENSITIVE=0
  413.             state.isosurface1->SetProperty, STYLE=2
  414.             WIDGET_CONTROL, state.wWireButton, SENSITIVE=1
  415.             WIDGET_CONTROL, state.wSolidButton, SENSITIVE=0
  416.             state.oWindow->Draw, state.oView
  417.             WIDGET_CONTROL, state.wBase, SENSITIVE=1
  418.             WIDGET_CONTROL, sEvent.top, SET_UVALUE=state, /NO_COPY
  419.         end; Case of SOLID
  420.  
  421.     endcase ; of uval
  422.  
  423. end ; end of em_option_event
  424.  
  425. ;----------------------------------------------------------------------------
  426. ;
  427. ;  Purpose:  Options menu event handler.
  428. ;
  429. pro em_view_event,  $
  430.     sEvent   ; IN: event structure
  431.  
  432.     WIDGET_CONTROL, sEvent.id, GET_UVALUE=uval
  433.  
  434.     case uval of
  435.  
  436.         ;  Hide or show the isosurfaces.
  437.         ;
  438.         'ISO' : begin
  439.             WIDGET_CONTROL, sEvent.top, GET_UVALUE=state, /NO_COPY
  440.             WIDGET_CONTROL, state.wBase, SENSITIVE=0
  441.             if (state.iso_on EQ 1) then begin ; Currently ON so turn OFF
  442.                 HIDE=1
  443.                 state.iso_on = 0
  444.                 WIDGET_CONTROL,sEvent.id, SET_VALUE='Isosurface (off)'
  445.             endif else begin ; Currently OFF so turn ON
  446.                 HIDE=0
  447.                 state.iso_on = 1
  448.                 WIDGET_CONTROL,sEvent.id, SET_VALUE='Isosurface (on)'
  449.             endelse
  450.  
  451.             ;  Update the view.
  452.             ;
  453.             state.isosurface1->SetProperty, HIDE=hide
  454.             state.oWindow->Draw, state.oView
  455.             WIDGET_CONTROL, state.wBase, SENSITIVE=1
  456.             WIDGET_CONTROL, sEvent.top, SET_UVALUE=state, /NO_COPY
  457.         end ; Case of ISO
  458.  
  459.         ;  Hide or show the bore holes.
  460.         ;
  461.         'BORES' : begin
  462.             WIDGET_CONTROL, sEvent.top, GET_UVALUE=state, /NO_COPY
  463.             WIDGET_CONTROL, state.wBase, SENSITIVE=0
  464.             if (state.bores_on EQ 1) then begin ; Currently ON so turn OFF
  465.                 HIDE=1
  466.                 state.bores_on = 0
  467.                 WIDGET_CONTROL,sEvent.id, SET_VALUE='BoreHoles (off)'
  468.             endif else begin ; Currently OFF so turn ON
  469.                 HIDE=0
  470.                 state.bores_on = 1
  471.                 WIDGET_CONTROL,sEvent.id, SET_VALUE='BoreHoles (on)'
  472.             endelse
  473.  
  474.             ;  Update the view.
  475.             ;
  476.             state.bore_obj->SetProperty, HIDE=hide
  477.             state.oWindow->Draw, state.oView
  478.             WIDGET_CONTROL, state.wBase, SENSITIVE=1
  479.             WIDGET_CONTROL, sEvent.top, SET_UVALUE=state, /NO_COPY
  480.         end ; Case of BORES
  481.  
  482.         ;  Hide or show the tanks.
  483.         ;
  484.         'TANKS' : begin
  485.             WIDGET_CONTROL, sEvent.top, GET_UVALUE=state, /NO_COPY
  486.             WIDGET_CONTROL, state.wBase, SENSITIVE=0
  487.             if (state.tanks_on EQ 1) then begin ; Currently ON so turn OFF
  488.                 HIDE=1
  489.                 state.tanks_on = 0
  490.                 WIDGET_CONTROL,sEvent.id,SET_VALUE='Tanks (off)'
  491.             endif else begin ; Currently OFF so turn ON
  492.                 HIDE=0
  493.                 state.tanks_on = 1
  494.                 WIDGET_CONTROL,sEvent.id,SET_VALUE='Tanks (on)'
  495.             endelse
  496.  
  497.             ;  Update the view.
  498.             ;
  499.             state.tanks->SetProperty, HIDE=hide
  500.             state.oWindow->Draw, state.oView
  501.             WIDGET_CONTROL, state.wBase, SENSITIVE=1
  502.             WIDGET_CONTROL, sEvent.top, SET_UVALUE=state, /NO_COPY
  503.         end ; Case of TANKS
  504.  
  505.         ;  Hide or show the enclosing box.
  506.         ;
  507.         'BOX' : begin
  508.             WIDGET_CONTROL, sEvent.top, GET_UVALUE=state, /NO_COPY
  509.             WIDGET_CONTROL, state.wBase, SENSITIVE=0
  510.             if (state.box_on EQ 1) then begin ; Currently ON so turn OFF
  511.                 HIDE=1
  512.                 state.box_on = 0
  513.                 WIDGET_CONTROL,sEvent.id, SET_VALUE='BoundingBox (off)'
  514.             endif else begin ; Currently OFF so turn ON
  515.                 HIDE=0
  516.                 state.box_on = 1
  517.                 WIDGET_CONTROL,sEvent.id, SET_VALUE='BoundingBox (on)'
  518.             endelse
  519.  
  520.             ;  Update the view.
  521.             ;
  522.             state.bounds->SetProperty, HIDE=hide
  523.             state.oWindow->Draw, state.oView
  524.             WIDGET_CONTROL, state.wBase, SENSITIVE=1
  525.             WIDGET_CONTROL, sEvent.top, SET_UVALUE=state, /NO_COPY
  526.         end ; Case of BOX
  527.  
  528.         ;  Hide or show the light icons.
  529.         ;
  530.         'LITES' : begin
  531.             WIDGET_CONTROL, sEvent.top, GET_UVALUE=state, /NO_COPY
  532.             WIDGET_CONTROL, state.wBase, SENSITIVE=0
  533.             if (state.lite_on EQ 1) then begin ; Currently ON so turn OFF
  534.                 HIDE=1
  535.                 state.lite_on = 0
  536.                 WIDGET_CONTROL,sEvent.id, SET_VALUE='Light Icons (off)'
  537.             endif else begin ; Currently OFF so turn ON
  538.                 HIDE=0
  539.                 state.lite_on = 1
  540.                 WIDGET_CONTROL,sEvent.id, SET_VALUE='Light Icons (on)'
  541.             end
  542.  
  543.             ;  Update the view.
  544.             ;
  545.             state.lite1_icon->SetProperty, HIDE=hide
  546.             state.lite2_icon->SetProperty, HIDE=hide
  547.             state.oWindow->Draw, state.oView
  548.             WIDGET_CONTROL, state.wBase, SENSITIVE=1
  549.             WIDGET_CONTROL, sEvent.top, SET_UVALUE=state, /NO_COPY
  550.         end ; Case of LITES
  551.  
  552.         ;  Hide or show the text annotation.
  553.         ;
  554.         'ANNO' : begin
  555.             WIDGET_CONTROL, sEvent.top, GET_UVALUE=state, /NO_COPY
  556.             WIDGET_CONTROL, state.wBase, SENSITIVE=0
  557.             if (state.text_on EQ 1) then begin ; Currently ON so turn OFF
  558.                 HIDE=1
  559.                 state.text_on = 0
  560.                 WIDGET_CONTROL,sEvent.id, SET_VALUE='Annotation (off)'
  561.             endif else begin ; Currently OFF so turn ON
  562.                 HIDE=0
  563.                 state.text_on = 1
  564.                 WIDGET_CONTROL,sEvent.id, SET_VALUE='Annotation (on)'
  565.             end
  566.  
  567.             ;  Update the view.
  568.             ;
  569.             state.annotation->SetProperty, HIDE=hide
  570.             state.oWindow->Draw, state.oView
  571.             WIDGET_CONTROL, state.wBase, SENSITIVE=1
  572.             WIDGET_CONTROL, sEvent.top, SET_UVALUE=state, /NO_COPY
  573.         end ; Case of LITES
  574.  
  575.         ;  Set the drag quality to low.
  576.         ;
  577.         'LOW': begin
  578.             WIDGET_CONTROL, sEvent.top, GET_UVALUE=state, /NO_COPY
  579.             WIDGET_CONTROL, state.wBase, SENSITIVE=0
  580.             state.dragq = 0
  581.             WIDGET_CONTROL, state.wDragLowButton, SENSITIVE=0
  582.             WIDGET_CONTROL, state.wDragHiButton, SENSITIVE=1
  583.             WIDGET_CONTROL, state.wBase, SENSITIVE=1
  584.             WIDGET_CONTROL, sEvent.top, SET_UVALUE=state, /NO_COPY
  585.         end; Case of LOW
  586.  
  587.         ;  Set the drag quality to high.
  588.         ;
  589.         'HIGH': begin
  590.             WIDGET_CONTROL, sEvent.top, GET_UVALUE=state, /NO_COPY
  591.             WIDGET_CONTROL, state.wBase, SENSITIVE=0
  592.             state.dragq = 2
  593.             WIDGET_CONTROL, state.wDragLowButton, SENSITIVE=1
  594.             WIDGET_CONTROL, state.wDragHiButton, SENSITIVE=0
  595.             WIDGET_CONTROL, state.wBase, SENSITIVE=1
  596.             WIDGET_CONTROL, sEvent.top, SET_UVALUE=state, /NO_COPY
  597.         end; Case of HIGH
  598.  
  599.         ;  Reset the initial orientation of the view.
  600.         ;
  601.         'RESET' : begin
  602.             WIDGET_CONTROL, sEvent.top, GET_UVALUE=state, /NO_COPY
  603.             WIDGET_CONTROL, state.wBase, SENSITIVE=0
  604.             ident = [[1.0,0,0,0], $
  605.                     [0.0,1,0,0], $
  606.                     [0.0,0,1,0], $
  607.                     [0.0,0,0,1]]
  608.             state.top3D->SetProperty, TRANSFORM=ident
  609.             state.oWindow->Draw, state.oView
  610.             WIDGET_CONTROL, state.wBase, SENSITIVE=1
  611.             WIDGET_CONTROL, sEvent.top, SET_UVALUE=state, /NO_COPY
  612.          end
  613.  
  614.     endcase ; of uval
  615.  
  616. end ; end of em_view_event
  617.  
  618. ;----------------------------------------------------------------------------
  619. ;
  620. ;  Purpose:  Main menu event handler
  621. ;
  622. pro d_tankleak_event, $
  623.     sEvent
  624.  
  625.     ;  Quit the application using the close box.
  626.     ;
  627.     if (TAG_NAMES(sEvent, /STRUCTURE_NAME) EQ $
  628.         'WIDGET_KILL_REQUEST') then begin
  629.         WIDGET_CONTROL, sEvent.top, /DESTROY
  630.         RETURN
  631.     endif
  632.  
  633.     WIDGET_CONTROL, sEvent.id, GET_UVALUE=uval
  634.  
  635.     case uval of
  636.  
  637.         ;  Recompute the isosurface with an new value and display it.
  638.         ;
  639.         'ISOVAL': begin
  640.             WIDGET_CONTROL, sEvent.top, GET_UVALUE=state, /NO_COPY
  641.  
  642.             textChange = ['void','comp1','comp2']
  643.             putTips, state.sText, state.wText[1], $
  644.                 textChange, [0,1,2]
  645.  
  646.             value = FLOAT(sEvent.value)
  647.             em_gen_iso, *state.ivol_ptr, *state.cvol_ptr, $
  648.                 value, state.low, $
  649.                 iso_verts, iso_polys, iso_color
  650.  
  651.             ;  Check for isodurface errors.
  652.             ;
  653.             if (N_ELEMENTS(iso_verts) EQ 0) then begin
  654.                 PRINT, 'Leaky_Tanks: Error in computing ' + $
  655.                     'isosurface, check iso_value.'
  656.                 WIDGET_CONTROL, state.wSlider, $
  657.                     SET_VALUE=state.previousSliderValue
  658.                 state.iso_value = state.previousSliderValue
  659.             endif else begin
  660.                 if (state.color_model EQ 0) then begin
  661.                     state.isosurface1->SetProperty, DATA=iso_verts, $
  662.                     POLYGONS=iso_polys, VERT_COLORS=0, COLOR=[255,0,255]
  663.                 endif else begin
  664.                     vert_colors = index_color2rgb(iso_color, 225.0)
  665.                     state.isosurface1->SetProperty, DATA=iso_verts, $
  666.                     POLYGONS=iso_polys, VERT_COLORS=vert_colors
  667.                 endelse ; else
  668.                 state.previousSliderValue = sEvent.value
  669.                 state.iso_value = sEvent.value
  670.             endelse
  671.  
  672.             ;  Redraw the view.
  673.             ;
  674.             WIDGET_CONTROL, state.wBase, /HOURGLASS
  675.             state.oWindow->Draw, state.oView
  676.  
  677.             ;  Rewrite the tip text.
  678.             ;
  679.             textChange = ['selecto','disp1','disp2']
  680.             putTips, state.sText, state.wText[1], $
  681.                textChange, [0,1,2]
  682.  
  683.             WIDGET_CONTROL, sEvent.top, SET_UVALUE=state, /NO_COPY
  684.         end ; Case of ISOVAL
  685.  
  686.         ;  Show element 1.
  687.         ;
  688.         'ELEM1' : begin
  689.             WIDGET_CONTROL, sEvent.top, GET_UVALUE=state, /NO_COPY
  690.             WIDGET_CONTROL, state.wBase, SENSITIVE=0
  691.  
  692.             textChange = ['void','comp1','comp2']
  693.             putTips, state.sText, state.wText[1], $
  694.                 textChange, [0,1,2]
  695.  
  696.             em_gen_iso, state.volume1, *state.cvol_ptr, $
  697.                 state.iso_value, $
  698.                 state.low, iso_verts, iso_polys, iso_color
  699.  
  700.             ;  Determine Color Model to Use.
  701.             ;
  702.             if (state.cvolume EQ 1) THEN color_model=0 else color_model=1
  703.  
  704.             if (N_ELEMENTS(iso_verts) EQ 0) then begin
  705.                 PRINT, 'Leaky_Tanks: Error in computing ' + $
  706.                     'isosurface, check iso_value.'
  707.             endif else begin
  708.                 if (color_model EQ 0) then begin
  709.                     state.isosurface1->SetProperty, DATA=iso_verts, $
  710.                         POLYGONS=iso_polys, VERT_COLORS=0, COLOR=[255,0,255]
  711.                 endif else begin
  712.                     vert_colors = index_color2rgb(iso_color, 225.0)
  713.                     state.isosurface1->SetProperty, DATA=iso_verts, $
  714.                         POLYGONS=iso_polys, VERT_COLORS=vert_colors
  715.                 endelse ; else
  716.             endelse
  717.  
  718.             ; Update the State Values.
  719.             ;
  720.             state.ivolume = 1
  721.             state.color_model = color_model
  722.             *state.ivol_ptr = state.volume1
  723.  
  724.             ; Update the view.
  725.             ;
  726.             WIDGET_CONTROL, state.wBase, /HOURGLASS
  727.             state.oWindow->Draw, state.oView
  728.  
  729.             textChange = ['selecto','disp1','disp2']
  730.             putTips, state.sText, state.wText[1], $
  731.                 textChange, [0,1,2]
  732.  
  733.             WIDGET_CONTROL, state.wBase, SENSITIVE=1
  734.             WIDGET_CONTROL, sEvent.top, SET_UVALUE=state, /NO_COPY
  735.         end ; Case of ELEM1
  736.  
  737.         ;  Show element 1.
  738.         ;
  739.         'ELEM2' : begin
  740.             WIDGET_CONTROL, sEvent.top, GET_UVALUE=state, /NO_COPY
  741.             WIDGET_CONTROL, state.wBase, SENSITIVE=0
  742.  
  743.             textChange = ['void','comp1','comp2']
  744.             putTips, state.sText, state.wText[1], $
  745.                 textChange, [0,1,2]
  746.  
  747.             em_gen_iso, state.volume2, *state.cvol_ptr, $
  748.                 state.iso_value, $
  749.                 state.low, iso_verts, iso_polys, iso_color
  750.  
  751.             ;  Determine Color Model to Use.
  752.             ;
  753.             if (state.cvolume EQ 2) THEN color_model=0 else color_model=1
  754.  
  755.             if (N_ELEMENTS(iso_verts) EQ 0) then begin
  756.                 PRINT, 'Leaky_Tanks: Error in computing ' + $
  757.                     'isosurface, check iso_value.'
  758.             endif else begin
  759.                 if (color_model EQ 0) then begin
  760.                     state.isosurface1->SetProperty, DATA=iso_verts, $
  761.                         POLYGONS=iso_polys, VERT_COLORS=0, COLOR=[255,0,255]
  762.                 endif else begin
  763.                     vert_colors = index_color2rgb(iso_color, 225.0)
  764.                     state.isosurface1->SetProperty, DATA=iso_verts, $
  765.                         POLYGONS=iso_polys, VERT_COLORS=vert_colors
  766.                 endelse ; else
  767.             endelse
  768.  
  769.             ;  Update the State Values.
  770.             ;
  771.             state.ivolume = 2
  772.             state.color_model = color_model
  773.             *state.ivol_ptr = state.volume2
  774.  
  775.             ;  Update the view.
  776.             ;
  777.             WIDGET_CONTROL, state.wBase, /HOURGLASS
  778.             state.oWindow->Draw, state.oView
  779.  
  780.             textChange = ['selecto','disp1','disp2']
  781.             putTips, state.sText, state.wText[1], $
  782.                 textChange, [0,1,2]
  783.  
  784.             WIDGET_CONTROL, state.wBase, SENSITIVE=1
  785.             WIDGET_CONTROL, sEvent.top, SET_UVALUE=state, /NO_COPY
  786.         end ; Case of ELEM2
  787.  
  788.         ;  Set the color of element 1 ( one color or multiple colors).
  789.         ;
  790.         'COLOR_ELEM1' : begin
  791.             WIDGET_CONTROL, sEvent.top, GET_UVALUE=state, /NO_COPY
  792.             WIDGET_CONTROL, state.wBase, SENSITIVE=0
  793.             textChange = ['void','comp1','comp2']
  794.             putTips, state.sText, state.wText[1], $
  795.                 textChange, [0,1,2]
  796.  
  797.             em_gen_iso, *state.ivol_ptr, state.volume1, $
  798.                 state.iso_value, $
  799.                 state.low, iso_verts, iso_polys, iso_color
  800.  
  801.             ;  Determine Color Model to Use.
  802.             ;
  803.             if (state.ivolume EQ 1) THEN color_model=0 else color_model=1
  804.  
  805.             if (N_ELEMENTS(iso_verts) EQ 0) then begin
  806.                 PRINT, 'Leaky_Tanks: Error in computing ' + $
  807.                     'isosurface, check iso_value.'
  808.             endif else begin
  809.                 if (color_model EQ 0) then begin
  810.                     state.isosurface1->SetProperty, DATA=iso_verts, $
  811.                         POLYGONS=iso_polys, VERT_COLORS=0, COLOR=[255,0,255]
  812.                 endif else begin
  813.                     vert_colors = index_color2rgb(iso_color, 225.0)
  814.                     state.isosurface1->SetProperty, DATA=iso_verts, $
  815.                         POLYGONS=iso_polys, VERT_COLORS=vert_colors
  816.                 endelse ; else
  817.             endelse
  818.  
  819.             ;  Update the State Values.
  820.             ;
  821.             state.cvolume = 1
  822.             state.color_model = color_model
  823.             *state.cvol_ptr = state.volume1
  824.  
  825.             ;  Update the view.
  826.             ;
  827.             WIDGET_CONTROL, state.wBase, /HOURGLASS
  828.             state.oWindow->Draw,state.oView
  829.             textChange = ['selecto','disp1','disp2']
  830.             putTips, state.sText, state.wText[1], $
  831.                 textChange, [0,1,2]
  832.  
  833.             WIDGET_CONTROL, state.wBase, SENSITIVE=1
  834.             WIDGET_CONTROL, sEvent.top, SET_UVALUE=state, /NO_COPY
  835.         end ; Case of COLOR_ELEM1
  836.  
  837.         ;  Set the color of element 1 ( one color or multiple colors).
  838.         ;
  839.         'COLOR_ELEM2' : begin
  840.             WIDGET_CONTROL, sEvent.top, GET_UVALUE=state, /NO_COPY
  841.             WIDGET_CONTROL, state.wBase, SENSITIVE=0
  842.  
  843.             textChange = ['void','comp1','comp2']
  844.             putTips, state.sText, state.wText[1], $
  845.                 textChange, [0,1,2]
  846.  
  847.             em_gen_iso, *state.ivol_ptr, state.volume2, state.iso_value, $
  848.                 state.low, iso_verts, iso_polys, iso_color
  849.  
  850.             ;  Determine Color Model to Use.
  851.             ;
  852.             if (state.ivolume EQ 2) THEN color_model=0 else color_model=1
  853.  
  854.             if (N_ELEMENTS(iso_verts) EQ 0) then begin
  855.                 PRINT, 'Leaky_Tanks: Error in computing ' + $
  856.                     'isosurface, check iso_value.'
  857.             endif else begin
  858.                 if (color_model EQ 0) then begin
  859.                     state.isosurface1->SetProperty, DATA=iso_verts, $
  860.                         POLYGONS=iso_polys, VERT_COLORS=0, COLOR=[255,0,255]
  861.                 endif else begin
  862.                     vert_colors = index_color2rgb(iso_color, 225.0)
  863.                     state.isosurface1->SetProperty, DATA=iso_verts, $
  864.                         POLYGONS=iso_polys, VERT_COLORS=vert_colors
  865.                 endelse ; else
  866.             endelse
  867.  
  868.             ;  Update the State Values.
  869.             ;
  870.             state.cvolume = 2
  871.             state.color_model = color_model
  872.             *state.cvol_ptr = state.volume2
  873.  
  874.             ;  Update the view.
  875.             ;
  876.             WIDGET_CONTROL, state.wBase, /HOURGLASS
  877.             state.oWindow->Draw,state.oView
  878.  
  879.             textChange = ['selecto','disp1','disp2']
  880.             putTips, state.sText, state.wText[1], $
  881.                 textChange, [0,1,2]
  882.  
  883.             WIDGET_CONTROL, state.wBase, SENSITIVE=1
  884.             WIDGET_CONTROL, sEvent.top, SET_UVALUE=state, /NO_COPY
  885.         end ; Case of COLOR_ELEM2
  886.  
  887.     endcase
  888. end
  889.  
  890. ;-----------------------------------------------------------------
  891. ;
  892. ;    PURPOSE : Cleanup procedure, restore colortable, destroy objects.
  893. ;
  894. pro d_tankleak_Cleanup, wBase
  895.  
  896.     WIDGET_CONTROL, wBase, GET_UVALUE=state, /NO_COPY
  897.  
  898.     ;  Destroy the top objects
  899.     ;
  900.     OBJ_DESTROY, state.oView
  901.     OBJ_DESTROY, state.f
  902.     OBJ_DESTROY, state.font
  903.     OBJ_DESTROY, state.font_small
  904.     OBJ_DESTROY, state.font_medium
  905.     OBJ_DESTROY, state.font_large
  906.     OBJ_DESTROY, state.oContainer
  907.     OBJ_DESTROY, state.oTrack
  908.     OBJ_DESTROY, state.oText
  909.     OBJ_DESTROY, state.oFont
  910.     PTR_FREE, state.ivol_ptr
  911.     PTR_FREE, state.cvol_ptr
  912.  
  913.     ;  Restore the color table.
  914.     ;
  915.     TVLCT, state.colorTable
  916.  
  917.     if WIDGET_INFO(state.groupBase, /VALID_ID) then $
  918.         WIDGET_CONTROL, state.groupBase, /MAP
  919.  
  920. end   ;  of D_Tankleak_Cleanup
  921.  
  922. ;-----------------------------------------------------------------
  923. ;
  924. ;    PURPOSE : Main procedure.
  925. ;
  926. pro d_tankleak, $
  927.     xdim=xdim, $       ; IN: (opt) x dimension of the viewing area.
  928.     ydim=ydim, $       ; IN: (opt) y dimension of the viewing area.
  929.     GROUP=group, $     ; IN: (opt) group identifier
  930.     APPTLB = appTLB    ; OUT: (opt) TLB of this application
  931.  
  932.     ; Check the validity of the group identifier.
  933.     ;
  934.     ngroup = N_ELEMENTS(group)
  935.     if (ngroup NE 0) then begin
  936.         check = WIDGET_INFO(group, /VALID_ID)
  937.         if (check NE 1) then begin
  938.             print,'Error, the group identifier is not valid'
  939.             print, 'Return to the main application'
  940.             RETURN
  941.         endif
  942.         groupBase = group
  943.     endif else groupBase = 0L
  944.  
  945.     ;  Get the current color vectors to restore
  946.     ;  when this application is exited.
  947.     ;
  948.     TVLCT, savedR, savedG, savedB, /GET
  949.  
  950.     ;  Build color table from color vectors.
  951.     ;
  952.     colorTable = [[savedR],[savedG],[savedB]]
  953.  
  954.  
  955.     ;  Determine the screen size.
  956.     ;
  957.     Device, GET_SCREEN_SIZE = screenSize
  958.  
  959.     ;  Set default values of the veiwing area size if not porvided.
  960.     ;
  961.     if (N_ELEMENTS(xdim) EQ 0) then begin
  962.         xdim = screenSize[0]*0.6
  963.     endif
  964.     if (N_ELEMENTS(ydim) EQ 0) then begin
  965.         ydim = 0.8 * xdim
  966.     endif
  967.  
  968.     ;  Restore the Volume Save Files so max and min are available
  969.     ;  for use when building cw_fslider.
  970.     ;
  971.     vol1_file = filepath('vol1.sav', $
  972.         SUBDIR=['examples','demo','demodata'])
  973.     vol2_file = filepath('vol2.sav', $
  974.         SUBDIR=['examples','demo','demodata'])
  975.  
  976.     restore, vol1_file
  977.     restore, vol2_file
  978.  
  979.     vol_min = MIN(volume1, max=vol_max)
  980.     vol_min2 = MIN(volume2, max=vol_max2)
  981.     vol_min = vol_min > vol_min2
  982.     vol_max = fix((vol_max < vol_max2) * 0.95)
  983.     
  984.     ;  Get the tips.
  985.     ;
  986.     sText = getTips(filepath('tankleak.tip', $
  987.         SUBDIR=['examples','demo', 'demotext']) )
  988.  
  989.     ;  Create the widgets starting with the top level base.
  990.     ;
  991.     if (N_ELEMENTS(group) EQ 0) then begin
  992.         wBase = WIDGET_BASE(/COLUMN, $
  993.             TITLE="Environmental Modeling Visualization", $
  994.             YPAD=0, XPAD=0, $
  995.             /TLB_KILL_REQUEST_EVENTS, $
  996.             TLB_FRAME_ATTR=1, MBAR=mbarbase )
  997.     endif else begin
  998.         wBase = WIDGET_BASE(/COLUMN, $
  999.             GROUP_LEADER=group, $
  1000.             TITLE="Environmental Modeling Visualization", $
  1001.             YPAD=0, XPAD=0, $
  1002.             /TLB_KILL_REQUEST_EVENTS, $
  1003.             TLB_FRAME_ATTR=1, MBAR=mbarbase)
  1004.     endelse
  1005.  
  1006.         ;  Create the Menu Bar
  1007.  
  1008.         ;  Create the file menu bar item that contains the quit button
  1009.         ;
  1010.         wFileButton = WIDGET_BUTTON(mbarbase,VALUE='File',/MENU)
  1011.  
  1012.             wQuitButton = WIDGET_BUTTON(wFileButton, $
  1013.                 VALUE = 'Quit',UVALUE='QUIT', $
  1014.                 EVENT_PRO='em_menu_event')
  1015.  
  1016.         ;  Create the option menu
  1017.         ;
  1018.         wOptionButton = WIDGET_BUTTON(mbarbase, $
  1019.             VALUE='Isosurface', /MENU)
  1020.  
  1021.             ;  Create the Shading Options Button.
  1022.             ;
  1023.             wShadingButton = WIDGET_BUTTON(wOptionButton, $
  1024.                 EVENT_PRO='em_option_event', $
  1025.                 VALUE='Shading',UVALUE='Shading',/MENU)
  1026.  
  1027.                 wFlatButton = WIDGET_BUTTON(wShadingButton, $
  1028.                     EVENT_PRO='em_option_event', $
  1029.                     VALUE='Flat',UVALUE='FLAT')
  1030.  
  1031.                 wGouraudButton = WIDGET_BUTTON(wShadingButton, $
  1032.                     EVENT_PRO='em_option_event', $
  1033.                     VALUE='Gouraud',UVALUE='GOURAUD')
  1034.  
  1035.            ;  Create the Style Options Button.
  1036.            ;
  1037.            wStyleButton = WIDGET_BUTTON(wOptionButton, $
  1038.                EVENT_PRO='em_option_event', $
  1039.                VALUE='Style',UVALUE='STYLE',/MENU)
  1040.  
  1041.                wWireButton = WIDGET_BUTTON(wStyleButton, $
  1042.                    EVENT_PRO='em_option_event', $
  1043.                    VALUE='Wire',UVALUE='WIRE')
  1044.  
  1045.                wSolidButton = WIDGET_BUTTON(wStyleButton, $
  1046.                    EVENT_PRO='em_option_event', $
  1047.                    VALUE='Solid',UVALUE='SOLID')
  1048.  
  1049.         ;  Create the View Menu.
  1050.         ; 
  1051.         wViewButton = WIDGET_BUTTON(mbarbase,VALUE='View',/Menu) 
  1052.  
  1053.             ;  Create the Object Visibility Button.
  1054.             ;
  1055.             wObjVizButton = WIDGET_BUTTON(wViewButton, $
  1056.                 EVENT_PRO='em_view_event', $
  1057.                 VALUE='Show Object', UVALUE='OBJVIZ',/MENU)
  1058.  
  1059.                 wIsoButton = WIDGET_BUTTON(wObjVizButton, $
  1060.                     EVENT_PRO='em_view_event', $
  1061.                     VALUE='Isosurface (on)',UVALUE='ISO')
  1062.  
  1063.                 wBoreButton = WIDGET_BUTTON(wObjVizButton, $
  1064.                     EVENT_PRO='em_view_event', $
  1065.                     VALUE='BoreHoles (on)',UVALUE='BORES')
  1066.  
  1067.                 wTanksButton = WIDGET_BUTTON(wObjVizButton, $
  1068.                     EVENT_PRO='em_view_event', $
  1069.                     VALUE='Tanks (on)',UVALUE='TANKS')
  1070.  
  1071.                 wBoxButton = WIDGET_BUTTON(wObjVizButton, $
  1072.                     EVENT_PRO='em_view_event', $
  1073.                     VALUE='Bounding Box (on)',UVALUE='BOX')
  1074.  
  1075.                 wLiteButton = WIDGET_BUTTON(wObjVizButton, $
  1076.                     EVENT_PRO='em_view_event', $
  1077.                     VALUE='Light Icons (off)',UVALUE='LITES')
  1078.  
  1079.             ;  Create the Drag Quality Options Button
  1080.             ;
  1081.             wDragButton = WIDGET_BUTTON(wViewButton, $
  1082.                 EVENT_PRO='em_view_event', $
  1083.                 VALUE='Drag Quality', UVALUE='DRAG',/MENU)
  1084.  
  1085.                 wDragLowButton = WIDGET_BUTTON(wDragButton, $
  1086.                     EVENT_PRO='em_view_event', $
  1087.                     VALUE='Low',UVALUE='LOW')
  1088.  
  1089.                 wDragHiButton = WIDGET_BUTTON(wDragButton, $
  1090.                     EVENT_PRO='em_view_event', $
  1091.                     VALUE='High',UVALUE='HIGH')
  1092.  
  1093.             ;  Create the transform reset button
  1094.             ;
  1095.             wResetMenu = WIDGET_BUTTON(wViewButton, $
  1096.                 EVENT_PRO='em_view_event', $
  1097.                 VALUE='Reset', /MENU)
  1098.  
  1099.                 wResetButton = WIDGET_BUTTON(wResetMenu, $
  1100.                     EVENT_PRO='em_view_event', $
  1101.                     VALUE='Reset Orientation',UVALUE='RESET')
  1102.  
  1103.         ;  Create the help/About button.
  1104.         ;
  1105.         wHelpButton = WIDGET_BUTTON(mbarbase, $
  1106.             VALUE='About', /HELP, /MENU)
  1107.  
  1108.             wAboutButton = WIDGET_BUTTON(wHelpButton, $
  1109.                 EVENT_PRO = 'em_menu_event', $
  1110.                 VALUE='About Environmental Modeling', UVALUE='INFO')
  1111.  
  1112.         ;  Create the first child of the top level base (wBase).
  1113.         ;
  1114.         wTopRowBase =  WIDGET_BASE(wBase, COLUMN=2)
  1115.  
  1116.             ; Create a base for the left column
  1117.             ;
  1118.             wLeftBase = WIDGET_BASE(wTopRowBase, $
  1119.                 /BASE_ALIGN_LEFT, /COLUMN, /FRAME)
  1120.  
  1121.                 ;  Create the Element Selection Area.
  1122.                 ;
  1123.                 wElemBase = WIDGET_BASE(wLeftBase, /COLUMN, /FRAME)
  1124.  
  1125.                     wIsoLabel1 = WIDGET_LABEL(wElemBase, $
  1126.                         VALUE="Element Selections", $
  1127.                         /ALIGN_CENTER)
  1128.  
  1129.                     wIsoLabel2 = WIDGET_LABEL(wElemBase, $
  1130.                         VALUE="Isosurface:", /ALIGN_LEFT)
  1131.  
  1132.                     wElemIsoBase = WIDGET_BASE(wElemBase,  $
  1133.                         /COLUMN, /EXCLUSIVE)
  1134.  
  1135.                         wElem1Toggle = WIDGET_BUTTON(wElemIsoBase, $
  1136.                             VALUE="Element 1", $
  1137.                             UVALUE='ELEM1', /NO_RELEASE, $
  1138.                             EVENT_PRO='d_tankleak_event')
  1139.  
  1140.                         wElem2Toggle = WIDGET_BUTTON(wElemIsoBase, $
  1141.                             VALUE="Element 2", $
  1142.                             UVALUE='ELEM2', /NO_RELEASE, $
  1143.                             EVENT_PRO='d_tankleak_event')
  1144.  
  1145.                     wIsoLabel3 = WIDGET_LABEL(wElemBase, $
  1146.                         VALUE="Shaded Colors:", /align_left)
  1147.  
  1148.                     wColorIsoBase = WIDGET_BASE(wElemBase, $
  1149.                         /COLUMN, /EXCLUSIVE)
  1150.  
  1151.                         wColor1Toggle = WIDGET_BUTTON(wColorIsoBase, $
  1152.                             VALUE="Element 1", $
  1153.                             UVALUE='COLOR_ELEM1', /NO_RELEASE, $
  1154.                             EVENT_PRO='d_tankleak_event')
  1155.  
  1156.                         wColor2Toggle = WIDGET_BUTTON(wColorIsoBase, $
  1157.                             VALUE="Element 2", $
  1158.                             UVALUE='COLOR_ELEM2', /NO_RELEASE, $
  1159.                             EVENT_PRO='d_tankleak_event')
  1160.  
  1161.                 ;  Create the SLIDER for the Isosurface Level
  1162.                 ;
  1163.                 wIsoBase = WIDGET_BASE(wLeftBase, /COLUMN, /FRAME)
  1164.  
  1165.                     wIsoLabel = WIDGET_LABEL(wIsoBase, $
  1166.                         VALUE="Isosurface Controls", $
  1167.                         /ALIGN_CENTER)
  1168.  
  1169.                     maxValue = FIX(vol_max)
  1170.                     wSlider = WIDGET_SLIDER(wIsoBase, $
  1171.                         VALUE=maxVAlue/2, $
  1172.                         MINIMUM=2, MAXIMUM=maxValue, $
  1173.                         UVALUE='ISOVAL')
  1174.  
  1175.             ;  Create a base for the right column.
  1176.             ;
  1177.             wRightBase = WIDGET_BASE(wTopRowBase, Column=1, /Frame)
  1178.  
  1179.                 wDraw3D = widget_draw(wRightBase, $
  1180.                     XSIZE=xdim, YSIZE=ydim, /BUTTON_EVENTS, $
  1181.                     UVALUE='DRAW', RETAIN=0, $
  1182.                     EVENT_PRO='em_win3d_event', /EXPOSE_EVENTS, $
  1183.                     GRAPHICS_LEVEL=2)
  1184.  
  1185.         ;  Create the tip widgets.
  1186.         ;
  1187.         wStatusBase = WIDGET_BASE(wBase, MAP=0, /ROW)
  1188.  
  1189.             nWidgets = 2
  1190.             wText = LONARR(nWidgets)
  1191.             widTips, wStatusBase, sText.text, XSIZE=36, $
  1192.                 YSIZE=3, NWIDGETS=nWidgets, wText
  1193.  
  1194.     ;  All the widget have been created, now realize them
  1195.     ;
  1196.     WIDGET_CONTROL, wBase, /REALIZE
  1197.  
  1198.     WIDGET_CONTROL, /HOURGLASS
  1199.  
  1200.     ;  Returns the top level base to the APPTLB keyword.
  1201.     ;
  1202.     appTLB = wBase
  1203.  
  1204.     ;  Size the tips widgets.
  1205.     ;
  1206.     sizeTips, wBase, wText, wStatusBase
  1207.  
  1208.     WIDGET_CONTROL, wDraw3D, GET_VALUE=oWindow
  1209.  
  1210.     ;  Set the state of the buttons.
  1211.     ;
  1212.     WIDGET_CONTROL, wElem1Toggle, SET_BUTTON=1
  1213.     WIDGET_CONTROL, wColor1Toggle, SET_BUTTON=1
  1214.  
  1215.     ;  Initialize the previous slider value to its actual value.
  1216.     ;
  1217.     previousSliderValue = (vol_max -vol_min) / 2.0
  1218.  
  1219.     ;  Create the identity matrix for transforms.
  1220.     ;
  1221.     ident = [[1.0,0,0,0], $
  1222.             [0.0,1,0,0], $
  1223.             [0.0,0,1,0], $
  1224.             [0.0,0,0,1]]
  1225.  
  1226.     ;  Define a few working colors.
  1227.     ;
  1228.     white  = [255,255,255]
  1229.     red    = [255,0,0]
  1230.     green  = [0,255,0]
  1231.     blue   = [0,0,255]
  1232.     purple = [255,0,255]
  1233.  
  1234.     ;  Define the Graphics View.
  1235.     ;
  1236.  
  1237.     oView = OBJ_NEW('IDLgrView', COLOR=[0,0,0], PROJECTION=1, $
  1238.         EYE= 51.0, $
  1239.         VIEWPLANE_RECT=[-50,-50,100,100], ZCLIP = [50, -100])
  1240.  
  1241.     ;  Create a centerd starting up text.
  1242.     ;
  1243.     myview = [-50, -50, 100, 100]
  1244.     textLocation = [myview[0]+0.5*myview[2], myview[1]+0.5*myview[3]]
  1245.  
  1246.     ;  Create and display the PLEASE WAIT text.
  1247.     ;
  1248.     oFont = OBJ_NEW('IDLgrFont', 'Helvetica', SIZE=18)
  1249.     oText = OBJ_NEW('IDLgrText', $
  1250.         'Starting up  Please wait...', $
  1251.         ALIGN=0.5, $
  1252.         LOCATION=textLocation, $
  1253.         COLOR=[255,255,0], FONT=oFont)
  1254.  
  1255.  
  1256.     ;  Prepare for the PLEASE WAIT text.
  1257.     ;
  1258.     ;  Add the temporary top object to the view.
  1259.     ;
  1260.     top_tmp = OBJ_NEW('IDLgrModel')
  1261.     oView->Add, top_tmp
  1262.  
  1263.     top_tmp->Add, oText
  1264.  
  1265.     oWindow->Draw, oView
  1266.  
  1267.     ;  Define top level model.
  1268.     ;
  1269.     top = OBJ_NEW('IDLgrModel')
  1270.  
  1271.     ;  Scale the top model. 
  1272.     ;
  1273.     sct = 0.8
  1274.     top->Scale, sct, sct, sct
  1275.  
  1276.     WIDGET_CONTROL, /HOURGLASS
  1277.  
  1278.     ;  Rotate the top model.
  1279.     ;
  1280.     top->Rotate, [1,0,0], -30
  1281.     top->Rotate, [0,1,0], 15
  1282.  
  1283.     ;  top3D is the top object for transformable objects.
  1284.     ;
  1285.     top3D = OBJ_NEW('IDLgrModel')
  1286.     top->Add, top3D
  1287.  
  1288.     ;  Add the top object to the view.
  1289.     ;
  1290.     oView->Add, top
  1291.  
  1292.     ;  Draw the Text and Title.
  1293.     ;
  1294.     font_small = OBJ_NEW('IDLgrFont', 'Helvetica', SIZE=16. )
  1295.     font_medium = OBJ_NEW('IDLgrFont', 'Helvetica', SIZE=18. )
  1296.     font_large = OBJ_NEW('IDLgrFont', 'Helvetica', SIZE=24. )
  1297.  
  1298.     annotation = OBJ_NEW('IDLgrModel')
  1299.     top->Add, annotation
  1300.  
  1301.     if (screenSize[0] EQ 640) THEN font=font_small else font = font_large
  1302.  
  1303.     ;  Add the Wait Text for computing Isosurfaces.
  1304.     ;
  1305.     iso_text = OBJ_NEW('IDLgrModel')
  1306.  
  1307.     iso_text1 = OBJ_NEW('IDLgrText', $
  1308.         'COMPUTING NEW ISOSURFACE:', $
  1309.         LOCATION=[-40,-35], $
  1310.         COLOR=[255,0,0], FONT=font)
  1311.  
  1312.     iso_text2 = OBJ_NEW('IDLgrText', $
  1313.         'Please Wait ...', $
  1314.         LOCATION= [-20,-41], $
  1315.         COLOR=[255,0,0], FONT=font)
  1316.  
  1317.     iso_text->Add, iso_text1
  1318.     iso_text->Add, iso_text2
  1319.     top->Add, iso_text
  1320.     iso_text->SetProperty, HIDE=1
  1321.  
  1322.     ;  Draw the red bounding box.
  1323.     ;
  1324.     extents = [-40.0, 40.0, -20.0, 20.0, -20.0, 0.0]
  1325.     bounds = em_extent_bounds(extents, top3D, red, green, blue)
  1326.  
  1327.     ;  Generate the Storage Tank Data.
  1328.     ;
  1329.     tank_points = [[0.0,0.0,-4.0],$
  1330.                    [5.0,0.0,-4.0],$
  1331.                    [5.0,0.0,4.0],$
  1332.                    [0.0,0.0,4.0]]
  1333.  
  1334.     mesh_obj, 6, tank_verts, tank_polys, tank_points, p1=16
  1335.  
  1336.     tank_points1 = [[0.0,0.0,-4.0],$
  1337.                    [5.0,0.0,-4.0],$
  1338.                    [5.0,0.0,4.0],$
  1339.                    [4.0,0.0,5.0],$
  1340.                    [1.0,0.0,5.0],$
  1341.                    [0.0,0.0,4.0]]
  1342.     mesh_obj, 6, tank_verts1, tank_polys1, tank_points1, p1=16
  1343.  
  1344.     ;  Generate the Graphics Objects for the Storage Tank Field.
  1345.     ;
  1346.     tanks = OBJ_NEW('IDLgrModel')
  1347.     top3D->Add, tanks
  1348.  
  1349.     ;  Tank #1.
  1350.     ;
  1351.     tank1 = OBJ_NEW('IDLgrModel')
  1352.     tanks->Add, tank1
  1353.     tank1_poly = OBJ_NEW('IDLgrPolygon', tank_verts1, poly=tank_polys1, $
  1354.         COLOR=white)
  1355.     tank1->Add, tank1_poly
  1356.  
  1357.     ; Tank #2.
  1358.     ;
  1359.     tank2 = OBJ_NEW('IDLgrModel')
  1360.     tanks->Add, tank2
  1361.     tank2_poly = OBJ_NEW('IDLgrPolygon', SHARE_DATA=tank1_poly, $
  1362.         POLYGONS=tank_polys1, COLOR=white)
  1363.     tank2->Add, tank2_poly
  1364.  
  1365.     ; Tank #3.
  1366.     ;
  1367.     tank3 = OBJ_NEW('IDLgrModel')
  1368.     tanks->Add, tank3
  1369.     tank3_poly = OBJ_NEW('IDLgrPolygon', share_data=tank1_poly, $
  1370.         POLYGONS=tank_polys1, COLOR=white)
  1371.     tank3->Add, tank3_poly
  1372.  
  1373.     ; Tank #4.
  1374.     ;
  1375.     tank4 = OBJ_NEW('IDLgrModel')
  1376.     tanks->Add, tank4
  1377.     tank4_poly = OBJ_NEW('IDLgrPolygon', share_data=tank1_poly, $
  1378.         POLYGONS=tank_polys1, COLOR=white)
  1379.     tank4->Add, tank4_poly
  1380.  
  1381.     ; Tank #5.
  1382.     ;
  1383.     tank5 = OBJ_NEW('IDLgrModel')
  1384.     tanks->Add, tank5
  1385.     tank5_poly = OBJ_NEW('IDLgrPolygon', share_data=tank1_poly, $
  1386.         POLYGONS=tank_polys1, COLOR=white)
  1387.     tank5->Add, tank5_poly
  1388.  
  1389.     ;  Translate each tank into place.
  1390.     ;
  1391.     z_depth = -8.0
  1392.     tank1->Translate, -24.0, 8.0, z_depth
  1393.     tank2->Translate, 0.0, 8.0, z_depth
  1394.     tank3->Translate, 24.0, 8.0, z_depth
  1395.     tank4->Translate, -12.0, -8.0, z_depth
  1396.     tank5->Translate, 12.0, -8.0, z_depth
  1397.  
  1398.     ;  Read the borehole data from: bores.dat.
  1399.     ;
  1400.     bore_file = filepath('bores0.dat', $
  1401.         SUBDIR=['examples','demo','demodata'])
  1402.     OPENR, bore_lun, bore_file, /GET_LUN
  1403.     bore_obj = read_bores(bore_lun, top3D, purple)
  1404.     CLOSE, bore_lun
  1405.     FREE_LUN, bore_lun
  1406.  
  1407.     ;  Generate the first isosurface.
  1408.     ;
  1409.     iso_COLOR=FLTARR(80,40,20)
  1410.     iso_value = (vol_max - vol_min) / 2.0
  1411.  
  1412.     WIDGET_CONTROL, wSlider, SET_VALUE=iso_value
  1413.  
  1414.     color_model = 0
  1415.     low = 1
  1416.     em_gen_iso, volume1, volume1, iso_value, low, iso_verts, $
  1417.          iso_polys, iso_color
  1418.  
  1419.     iso_model1 = OBJ_NEW('IDLgrModel')
  1420.     top3D->Add, iso_model1
  1421.  
  1422.     if (color_model EQ 0) then begin
  1423.         isosurface1 = OBJ_NEW('IDLgrPolygon', iso_verts, $
  1424.         POLYGONS=iso_polys, $
  1425.         COLOR=[250,0,250])
  1426.     endif else begin
  1427.         vert_colors = index_color2rgb(iso_color, 225.0)
  1428.         isosurface1 = OBJ_NEW('IDLgrPolygon', iso_verts, $
  1429.         POLYGONS=iso_polys, $
  1430.         vert_COLOR=vert_colors)
  1431.     endelse ; else
  1432.  
  1433.     iso_model1->Add, isosurface1
  1434.     iso_model1->translate, -40.0, -20.0, -20.0 ; Translate into place
  1435.  
  1436.     ;  Get and Set properties on the bounds of the geometry.
  1437.     ;
  1438.     xr = [extents[0],extents[1]]
  1439.     yr = [extents[2],extents[3]]
  1440.     zr = [extents[4],extents[5]]
  1441.  
  1442.     ;  Generate the light sources.
  1443.     ;
  1444.     li_xverts = [-1.0, 1.0, 0.0, 0.0, 0.0, 0.0]
  1445.     li_yverts = [0.0, 0.0, 1.0, -1.0, 0.0, 0.0]
  1446.     li_zverts = [0.0, 0.0, 0.0, 0.0, 1.0, -1.0]
  1447.     li_pl = [2,0,1,$
  1448.              2,2,3,$
  1449.              2,4,5]
  1450.  
  1451.     ;  Generate an ambient light source.
  1452.     ;
  1453.     lite0 = OBJ_NEW('IDLgrLight', TYPE=0, COLOR=[128,128,128])
  1454.     top->Add, lite0
  1455.  
  1456.     ;  Generate the first light source.
  1457.     ;
  1458.     lite1_icon = OBJ_NEW('IDLgrModel')
  1459.     top->Add,lite1_icon
  1460.     lite1_x = 40.0
  1461.     lite1_y = -20.0
  1462.     lite1_z = 10.0
  1463.     lite1_icon_pl = OBJ_NEW('IDLgrPolyline',li_xverts,li_yverts,li_zverts,$
  1464.         POLYLINES=li_pl, COLOR=white)
  1465.  
  1466.     lite1_icon->Add,lite1_icon_pl
  1467.     lite1_icon->Translate, lite1_x, lite1_y, lite1_z
  1468.  
  1469.     ;  Add a Positional Light type = 1.
  1470.     ;
  1471.     lite1 = OBJ_NEW('IDLgrLight',  $
  1472.         LOCATION=[lite1_x, lite1_y, lite1_z], TYPE=1)
  1473.     top->Add,lite1
  1474.  
  1475.     ;  Generate the second light source.
  1476.     ;
  1477.     lite2_icon = OBJ_NEW('IDLgrModel')
  1478.     top->Add,lite2_icon
  1479.  
  1480.     lite2_x = -40.0
  1481.     lite2_y = -20.0
  1482.     lite2_z = 10.0
  1483.     lite2_icon_pl = OBJ_NEW('IDLgrPolyline', li_xverts, li_yverts, li_zverts,$
  1484.         POLYLINES=li_pl, COLOR=white)
  1485.     lite2_icon->Add,lite2_icon_pl
  1486.     lite2_icon->translate, lite2_x, lite2_y, lite2_z
  1487.  
  1488.     ;  Add a Positional Light type = 1.
  1489.     ;
  1490.     lite2 = OBJ_NEW('IDLgrLight',  $
  1491.         LOCATION=[lite2_x, lite2_y, lite2_z], TYPE=1)
  1492.     top->Add, lite2
  1493.  
  1494.     ;  Initially turn the Light Icons Off.
  1495.     ;
  1496.     lite1_icon->SetProperty, HIDE=1
  1497.     lite2_icon->SetProperty, HIDE=1
  1498.  
  1499.  
  1500.     ;  Set the initial state of objects (on or off).
  1501.     ;
  1502.     iso_on   = 1
  1503.     bores_on = 1
  1504.     tanks_on = 1
  1505.     box_on   = 1
  1506.     text_on  = 1
  1507.     lite_on  = 0
  1508.  
  1509.     ;  Desensitive the initial settings.
  1510.     ;
  1511.     WIDGET_CONTROL, wDragLowButton, SENSITIVE=0
  1512.     WIDGET_CONTROL, wGouraudButton, SENSITIVE=0
  1513.     WIDGET_CONTROL, wSolidButton, SENSITIVE=0
  1514.  
  1515.     ;  Define two text strings.
  1516.     ;
  1517.     displayText = 'The display is interactive with the left mouse button'
  1518.     computingText = 'Computing new isosurface: Please wait... '
  1519.  
  1520.     ;  Add the trackball object for interactive change
  1521.     ;  of the scene orientation.
  1522.     ;
  1523.     oTrack = OBJ_NEW('Trackball', [xdim/2.0, ydim/2.0], xdim/2.0)
  1524.  
  1525.     oContainer = OBJ_NEW('IDLgrContainer')
  1526.     oContainer->Add, oView
  1527.     oContainer->Add, oTrack
  1528.  
  1529.     state = {center: xdim/2., $            ; X Center of drawing area 
  1530.           radius: ydim/2, $                ; Sphere radius (1/2 drawing area height)
  1531.           size_2: xdim/2., $               ; Shpere size (1/2 drawing area width)
  1532.           btndown: 0b, $                   ; Mouse 0=not pressed, pressed otherwise
  1533.           wDraw3D: wDraw3D, $              ; Widget draw ID
  1534.           annotation: annotation, $        ; Annotation Model   
  1535.           top3D: top3D, $                  ; Topmodel for 3-D
  1536.           iso_text: iso_text, $            ; Model for isosurface text 
  1537.           bounds: bounds, $                ; Box object
  1538.           lite1_icon: lite1_icon, $        ; Light icon 1 model
  1539.           lite2_icon: lite2_icon, $        ; Light icon 2 model
  1540.           bore_obj: bore_obj, $            ; Bore holes object
  1541.           tanks: tanks, $                  ; Tanks model
  1542.           tank1_poly: tank1_poly, $        ; Tanks polyline objects
  1543.           tank2_poly: tank2_poly, $
  1544.           tank3_poly: tank3_poly, $
  1545.           tank4_poly: tank4_poly, $
  1546.           tank5_poly: tank5_poly, $
  1547.           isosurface1: isosurface1, $      ; Isosurface (polygon) object
  1548.           iso_value: iso_value, $          ; Isosurface value
  1549.           low: low, $                      ; Show low values of the isosurface
  1550.           DisplayText: displayText, $      ; Text object
  1551.           ComputingText: computingText, $  ; 'Computing' string
  1552.           WBase: wBase, $                  ; Top level base
  1553.           WWireButton: wWireButton, $      ; Functionality buttons
  1554.           WSolidButton: wSolidButton, $
  1555.           WDragHiButton: wDragHiButton, $
  1556.           WDragLowButton: wDragLowButton, $
  1557.           WFlatButton: wFlatButton, $
  1558.           WGouraudButton: wGouraudButton, $
  1559.           WSlider: wSlider, $              ; Isosurface value slider
  1560.           OTrack: oTrack, $                ; Trackball object
  1561.           OContainer: oContainer, $        ; Container object
  1562.           volume1: volume1, $              ; Volume data of element 1 
  1563.           volume2: volume2, $              ; Volume data of element 2
  1564.           ivol_ptr: ptr_new(volume1), $    ; Pointer ot volume data 1
  1565.           cvol_ptr: ptr_new(volume1), $    ; Pointer ot volume data 2
  1566.           ivolume: 1, $                    ; Current volume for element x
  1567.           cvolume: 1, $                    ; Current color for element x
  1568.           color_model: color_model, $      ; Color model
  1569.           iso_verts: iso_verts, $          ; Isosurface vertices
  1570.           iso_polys: iso_polys, $          ; Isosurface polylines coordinates
  1571.           iso_color: iso_color, $          ; Isosurface color vertex
  1572.           iso_on: iso_on, $                ; Object : 0= hide, 1 = showing
  1573.           bores_on: bores_on, $
  1574.           tanks_on: tanks_on, $
  1575.           box_on: box_on, $
  1576.           text_on: text_on, $
  1577.           lite_on: lite_on, $
  1578.           OView: oView, $                  ; View object
  1579.       f: font, $                       ; Font objects
  1580.           Font: font, $
  1581.           Font_small: font_small, $
  1582.           Font_medium: font_medium, $
  1583.           Font_large: font_large, $
  1584.           ColorTable: colortable, $        ; Color table to restore
  1585.           dragq : 0, $                     ; Drag quality: 0=low, 1=med., 2=high
  1586.           PreviousSliderValue: previousSliderValue, $ : As is
  1587.           WText: wText, $                  ; Widget text IDs for tips
  1588.           SText: sText, $                  ; Text structure for tips
  1589.           OText: oText, $                  ; Text object
  1590.           OFont: oFont, $                  ; Font object
  1591.           OWindow: oWindow, $              ; Window object
  1592.           groupBase: groupBase $           ; Base of Group Leader
  1593.          }
  1594.  
  1595.     ;  Set the isosurface shading to Gouraud.
  1596.     ;
  1597.     isosurface1->SetProperty, SHADING=1
  1598.  
  1599.     ;  Draw the screen. Remove the starting up text.
  1600.     ;
  1601.     top_tmp->Remove, oText
  1602.     oWindow->Draw, oView
  1603.  
  1604.     WIDGET_CONTROL, wBase, SET_UVALUE=state, /NO_COPY
  1605.  
  1606.     XMANAGER, 'd_tankleak', wBase, $
  1607.         /NO_BLOCK, $
  1608.         CLEANUP='d_tankleak_Cleanup'
  1609.  
  1610. end ; D_Tankleak
  1611.